#pragma once
#include "DXAMLCommon.h"

#include "CInterlockedReferenceCount.h"


class CRenderTarget;
class BrushCloneList;
class HWFrameData;
class HWInstance;
class HWCompTreeNode;
class CUIElement;
class HWTextureManager;
class SurfaceCache;
class HWCrossFrameResources;
class CBrush;
class SolidColorBrushClone;
class TransformAndClipStack;
class CMILMatrix;
class CTileIterator;
class CImageBrush;
class CBorder;
class CRectangle;
class CCompositeVectorBuffer;
class HWTexture;



class HWWalk :
	public CInterlockedReferenceCount
{

public: 
	static HRESULT Create(CRenderTarget * pRenderTarget, HWWalk * * ppHwWalk);
	BrushCloneList * GetBrushCloneList();
	HWFrameData * GetFrameData();
	void StoreRootNode(HWCompTreeNode * pRoot);
	HWInstance * GetLastInstance();
	void SetLastInstance(HWInstance * pInstance);
	HRESULT UpdateLastInstanceFromContent(xvector<HWInstance *> * pRenderData);
	void UpdateLastInstanceFromSubgraph(CUIElement * pUIElement, const struct HWRenderParams & rp);
	HRESULT PushCompNodeStartBoundary(HWCompTreeNode * pCompNode, XUINT32 * pIndex);
	void UpdateCompNodeStartBoundary(HWCompTreeNode * pCompNode, HWInstance * pInstance, XUINT32 index);
	HRESULT PushCompNodeEndBoundary(HWCompTreeNode * pCompNode, HWInstance * pInstance);
	xvector<HWInstance *> * GetOverrideRenderDataList();
	void SetOverrideRenderDataList(xvector<HWInstance *> * pOverrideList);
	HWTextureManager * GetTextureManager();
	SurfaceCache * GetSurfaceCache();
	virtual HRESULT DelayedResourceCleanup();
	void HandleDeviceLost();
	HRESULT RenderRoot(CUIElement * pVisualRoot, CRenderTarget * pRenderTarget, HWInstance * pPersistentRenderDataSentinel, HWCrossFrameResources * pCrossFrameResources, HWFrameData * pPreviousFrameData, XUINT32 backgroundColor, XUINT32 forceRedraw, XUINT32 needsToReleaseHardwareResources, XUINT32 isOverdrawHeatMapEnabled, TransformAndClipStack * pPrependTransformAndClip, const CMILMatrix & displayOrientationTransform, const CMILMatrix & displayOrientationTransformInverse, XUINT32 forceAllSlotsDirty, HWCompTreeNode * * ppRootNode, BrushCloneList * * ppBrushCloneList, XUINT32 * pHasRenderedContent);
	static HRESULT GetBrushParameters(HWTextureManager * pTextureManager, SurfaceCache * pSurfaceCache, struct HWRenderParams & localRP, CBrush * pBrush, SolidColorBrushClone * pBrushClone, const struct XRECTF_WH * pBounds, XUINT32 allowPushBrushClip, float * pLocalOpacity, XUINT32 * pBrushMask, XUINT32 * pHasBrush, enum AddressEdgeMode * pAddressEdgeMode, CTileIterator * pTileIterator, CMILMatrix * pBrushTextureTransform, TransformAndClipStack * pTransformsAndClips);
	static HRESULT ImageBrushRenderContent(xvector<HWInstance *> * pRenderData, CImageBrush * pImageBrush, struct XRECTF_WH & imageRect, const struct HWRenderParams & myRP);
	static XUINT32 GetHollowNinegridForBorderBrush(CBorder * pBorder, struct XRECTF_RB * pNinegrid);
	static HRESULT VerifyCompositionPathCount(CUIElement * pUIElement);

private: 
	HWWalk(CRenderTarget *);
	virtual ~HWWalk();
	HRESULT Initialize();
	//static HRESULT RectangleRenderContent(CRectangle * pRectangle, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, const struct HWElementRenderParams & myElementRP);
	//static HRESULT BorderRenderContent(CBorder * pBorderElement, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, const struct HWElementRenderParams & myElementRP);
	//static HRESULT MaskCombinedRenderHelper(CUIElement * pUIElement, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, const struct HWElementRenderParams & myElementRP, IMaskPartRenderParams * pStrokeMaskPart, IMaskPartRenderParams * pFillMaskPart);
	//static HRESULT RenderAlphaMask(CUIElement * pUIElement, const struct HWRenderParams & myRP, const CMILMatrix * pRealizationScale, HWShapeRealization * pHwShapeRealization, XUINT32 createdFreshRealization, XUINT32 fMaskDirty, CCompositeVectorBuffer * * ppVectorBuffer, XUINT32 * pNeedsRealizationUpdate);
	//static HRESULT MaskPartEnsureRealizationTexture(CUIElement * pUIElement, const struct HWRenderParams & myRP, IMaskPartRenderParams * pParams, XUINT32 width, XUINT32 height, HWShapeRealization * pHwShapeRealization, SolidColorBrushClone * pBrushClone);
	//static HRESULT MaskPartRenderHelper(CUIElement * pUIElement, const struct XPOINTF & shapeOffset, float realizationScaleX, float realizationScaleY, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, IMaskPartRenderParams * pParams, SolidColorBrushClone * pBrushClone, HWTexture * pHwPartTexture);
	//static HRESULT MaskRasterizeSoftware(CUIElement * pUIElement, CCompositeVectorBuffer * pVectorBuffer, struct IPALSurface * pFillDestSurface, struct IPALSurface * pStrokeDestSurface);
	//static HRESULT ImageRenderContent(CImage * pImage, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP);
	//static HRESULT GlyphsRenderContent(CGlyphs * pGlyphs, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT TextBlockRenderContent(CTextBlock * pRichTextBlock, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT TextBlockPostChildrenRender(CTextBlock * pTextBlock, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT RichTextBlockRenderContent(CRichTextBlock * pRichTextBlock, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT RichTextBlockPostChildrenRender(CRichTextBlock * pRichTextBlock, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT RichTextBlockOverflowRenderContent(CRichTextBlockOverflow * pRichTextBlockOverflow, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT RichTextBlockOverflowPostChildrenRender(CRichTextBlockOverflow * pRichTextBlockOverflow, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT TextBoxViewRenderContent(CTextBoxView * pTextBoxView, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & rp, const struct HWElementRenderParams & myElementRP);
	//static HRESULT MediaElementRenderContent(CMediaBase * pMediaBase, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP);
	//static HRESULT LayoutTransitionElementRenderTarget(CLayoutTransitionElement * pLTElement, const struct HWRenderParams & lteRP, struct D2DRenderContext & d2dRenderContext);
	//static HRESULT CacheRender(CUIElement * pUIElement, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, struct D2DRenderContext & d2dRenderContext);
	//static HRESULT SoftwareEnsureRealizationTexture(CUIElement * pUIElement, const struct HWRenderParams & myRP, HWCacheRealization * pHwCacheRealization);
	//static HRESULT CacheRenderSoftware(XUINT32 enableShapeOptimization, CUIElement * pUIElement, const CMILMatrix * pRealizationScale, CRenderTarget * pRenderTarget, CCompositeVectorBuffer * * ppVectorBuffer);
	//static HRESULT CacheRasterizeSoftware(CUIElement * pUIElement, CCompositeVectorBuffer * pVectorBuffer, struct IPALSurface * pDestSurface);
	//static HRESULT D2DEnsureRealizationTexture(struct D2DRenderContext & d2dRenderContext, CUIElement * pUIElement, const struct HWRenderParams & myRP, HWCacheRealization * pHwCacheRealization);
	//static HRESULT WaitForD2DRasterization(struct IPALOptimizedGraphicsDevice * pDevice);
	//static HRESULT PanelRenderContent(CPanel * pPanel, xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, const struct HWElementRenderParams & myElementRP);
	//static HRESULT PopupRenderChild(CPopup * pPopup, const struct HWRenderParams & myRP, struct D2DRenderContext & d2dRenderContext);
	//static HRESULT PopupRootRenderChildren(CPopupRoot * pPopupRoot, const struct HWRenderParams & rp, struct D2DRenderContext & d2dRenderContext);
	//static HRESULT Render(CUIElement * pUIElement, const struct HWRenderParams & parentRP, struct D2DRenderContext & d2dRenderContext, XUINT32 redirectedDraw);
	//static HRESULT RenderProperties(CUIElement * pUIElement, const struct HWRenderParams & parentRP, struct D2DRenderContext & d2dRenderContext, XUINT32 requiresRedirectedDrawing, XUINT32 * pSkipRenderWhileInheritedCollapsed, XUINT32 * pSkipRenderWhileTransparent, XUINT32 * pSkipRenderWhileClippedOut, XUINT32 * pSkipRenderWhileLayoutClippedOut, XUINT32 * pSkipRenderWhileTransformTooSmall);
	//static HRESULT RenderContentAndChildren(CUIElement * pUIElement, struct HWRenderParams & myRP, struct D2DRenderContext & d2dRenderContext, XUINT32 requiresRedirectedDrawing, XUINT32 elementHasCompNode);
	//static HRESULT RenderChildren(CUIElement * pPopupRoot, const struct HWRenderParams & rp, struct D2DRenderContext & d2dRenderContext);
	//static HRESULT LeaveSceneRecursive(CUIElement *);
	//static CUIElement * GetRedirectionTarget(CUIElement * pUIE);
	//static XUINT32 IsAbsolutelyPositioned(CUIElement * pUIE);
	//static HRESULT CreateCompositionNode(CUIElement * pUIElement, struct HWRenderParams & rp, HWCompTreeNode * pRedirectionTarget, const TransformAndClipStack * pTransformsFromRedirectionTargetToRedirectionCompNode, HWCompTreeNode * * ppCompNode);
	//static HRESULT CreateBrushClones(CUIElement * pUIElement, const struct HWRenderParams & rp, struct HWElementRenderParams & elementRP);
	//static void CalculateBrushTransform(const CMILMatrix * pBrushToElementTransformInPixelCoords, const struct XRECTF_WH * pBrushNaturalSize, CMILMatrix * pElementToBrushTransformInTextureCoords);
	//static HRESULT CalculateTileBrushTransformAndClip(CTileBrush * pTileBrush, XUINT32 allowPushBrushClip, const struct XRECTF_WH * pBounds, CMILMatrix * pPositionToTexture, CMILMatrix * pBrushToElement, TransformAndClipStack * pTransformsAndClips);
	//static HRESULT PushBrushClip(const struct XRECTF_WH * pBrushNaturalSize, const CMILMatrix * pLocalSpaceBrushToElementTransform, TransformAndClipStack * pTransformsAndClips);
	//static HRESULT IntersectClipInCompNodeSpace(CGeometry * pClip, TransformAndClipStack * pCombinedTransformsAndClipsToCompNode, XUINT32 * pSkipRenderWhileClippedOut);
	//static HRESULT AddRectangleWithBrushParameters(xvector<HWInstance *> * pRenderData, const struct HWRenderParams & myRP, const struct XRECTF_WH & rect, const struct XRECTF_WH & brushBounds, CBrush * pBrush, SolidColorBrushClone * pBrushClone, const struct XRECTF_RB * pNinegrid, HWTexture * pShapeHwTexture, XUINT32 fIsHollow);
	//static XUINT32 IsShapeMaskRequiredForRectangle(CRectangle * pRectangleElement);
	//static XUINT32 IsShapeMaskRequiredForBorder(CBorder * pBorder);
	//static void GetSizeFromVectorBuffer(CCompositeVectorBuffer * pVectorBuffer, XUINT32 * pWidth, XUINT32 * pHeight);
	//static void GetWorldScale(const struct HWRenderParams & myRP, CMILMatrix * pWorldScale);
	CRenderTarget * m_pRenderTargetNoRef;
	HWTextureManager * m_pTextureManager;
	SurfaceCache * m_pSurfaceCache;
	BrushCloneList * m_pCurrentBrushCloneListNoRef;
	HWFrameData * m_pCurrentFrameDataNoRef;
	HWCompTreeNode * m_pCurrentRootNode;
	HWInstance * m_pLastInstanceNoRef;
	xvector<HWInstance *> * m_pOverrideRenderDataListNoRef;
	xvector<xpair<HWCompTreeNode *,HWInstance *> > m_startBoundaries; 
	xvector<xpair<HWCompTreeNode *,HWInstance *> > m_endBoundaries;




};


